#include<iostream>
using namespace std;
#include<unistd.h>
#include<sys/types.h>
#include<sys/wait.h>
#include<stdlib.h>
#include<string>
#include<string.h>
#include<stdio.h>
#include<cstdio>
#include<cstdlib>
const int basesize=1024;

const int garvnum=64;
//全局命令
char* gargv[garvnum];
int gargc=0;


string GetUserName()
{
   string name=getenv("USER");
   return name.empty()?"NoUser":name;
}
string GetHostName()
{
   string hostname=getenv("HOSTNAME");
   return hostname.empty()?"NoHost":hostname;
}
string GetPWD()
{
    string pwd=getenv("PWD");
    return pwd.empty()?"NoPWD":pwd;
}

string Commandline()
{
  //[gxy@iZ2ze2x8nrwwd0xw2vzsrhZ lesson20]
   char command_line[basesize];
   snprintf(command_line,basesize,"[%s@%s %s]$",GetUserName().c_str(), GetHostName().c_str(), GetPWD().c_str());
   return command_line;
}
void PrintCommand()
{
    printf("%s",Commandline().c_str());
    fflush(stdout);
}

bool GetCommandLine(char command_buffer[],int basesize)
{
   char* result=fgets(command_buffer, basesize,stdin);//stdin 标准输入
    if(!result)
    {
          return  false;
    }
    //末尾有个换行符 还要考虑这个命令是不是空指令 也就是只有换行符
    command_buffer[strlen(command_buffer)-1]=0;
    if(strlen(command_buffer)==0)
    {
      return false;
    }
    return true;

}
void  ParseCommandLine(char command_buffer[], int sz)
{
      (void)sz;
      memset(gargv,0,sizeof(gargv));
      gargc=0;
      const char* interval=" ";
      gargv[gargc++]=strtok(command_buffer,interval);//必须写第一个，因为第一次分析命令和之后分析命令 写的格式不一样

     // while((bool)(gargv[gargc++]=strtok(nullptr,interval)));//最后一个为空的时候也存进去 因为你也有空命令的时候，一起分析了
      while((bool)(gargv[gargc++] = strtok(nullptr, interval)));
      gargc--;

}
bool ExecuteCommand()
{
  //让子进程进行
   pid_t id=fork();
   if(id<0)
   {
     cout<<"执行失败"<<endl;
   }
   if(id==0)//子进程
   {
     execvp(gargv[0],gargv);
     exit(1);
   }
   int status=0;
   if(id>0)
   {
     pid_t rid=waitpid(id,&status,0);
     if(rid>0)//
     {
       return true;
     }
   
    
   }
   return false;

}
int main()
{
  char command_buffer[basesize];
  while(true)
  {
    PrintCommand();//打印命令行
    
    if(!GetCommandLine(command_buffer,basesize) )   // 2. 获取用户命令
        {
            continue;
        }

     //"ls -a -b -c -d"->"ls" "-a" "-b" "-c" "-d"
        ParseCommandLine(command_buffer, strlen(command_buffer)); // 3. 分析命令

         ExecuteCommand();   // 4. 执行命令
  }
}
